package fnord.jovian.tango;

import java.awt.*;
import java.awt.geom.*;

public class TheSlider implements TheObject {

	private Ellipse2D.Double _circle;
	private Rectangle2D.Double _bar;
	private Color _barColor = Color.gray, _circleColor = new Color(100,100,100);
	private double _length, _dragX, _circleOff = 0,
	_textWidth = 15, _circleSize = 18, _barHeight = 2;
	private Point _point;
	private boolean _dragging = false;


	public TheSlider(double length, double w) {
		_length = length;
		_circle = new Ellipse2D.Double(0,0,_circleSize,_circleSize);
		_bar = new Rectangle2D.Double(0,0,w - _circleSize - _textWidth,_barHeight);
	}

	@Override
	public void paint(Graphics2D g) {
		g.setFont(new Font("Arial", Font.BOLD, (int)Math.round(12.0 * Toolkit.getDefaultToolkit().getScreenResolution() / 72.0)));
		g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
		FontMetrics fm = g.getFontMetrics();
		int fontHeight = fm.getAscent() + fm.getDescent();
		g.setColor(_barColor);
		g.fill(_bar);
		g.setColor(_circleColor);
		g.fill(_circle);
		g.setColor(Color.WHITE);
		int val = (int)(Math.round(_length*(_circle.getX() + 5.0 - _bar.getX())/_bar.getWidth()));
		if (val < 0)
			val = 0;
		g.drawString(String.valueOf(val), (int)(_bar.getX() - _circleSize/2.0 - _textWidth), (int)(_circle.getY() + fm.getAscent() + (_circle.getHeight() - fontHeight)/2.0));
		g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
	}

	@Override
	public boolean contains(Point p) {
		return _circle.contains(p);
	}

	@Override
	public boolean containsClick(Point p) {
		if (_circle.contains(p)) {
			_dragX = p.getX() - _circle.getX();
			_dragging = true;
		}
		return contains(p);
	}

	@Override
	public boolean containsDrag(Point p) {
		_point = p;
		if (_dragging) {
			dragAction();
			return true;
		}
		return false;
	}

	private void dragAction() {
		double next = (_point.getX() - _dragX) - _bar.getX() + _circleSize/2.0;
		double val = (Math.round(_length*(next)/_bar.getWidth()));
		if (_length == 0)
			_circleOff = 0;
		else {
			if (Math.floor(val)/_length > 1)
				_circleOff = _bar.getWidth();
			else if (val < 0)
				_circleOff = 0;
			else
				_circleOff = next;
			setLocation(getX(),getY());
		}
	}

	public double getValue() {
		return (Math.round(_length*(_circle.getX() + 5.0 - _bar.getX())/_bar.getWidth()));
	}

	@Override
	public boolean containsUp(Point p) {
		if (_circle.contains(p)) {
			_dragging = false;
			return true;
		}
		return false;
	}

	@Override
	public double getX() {
		return (_bar.getX() - _textWidth - _circleSize/2.0);
	}

	@Override
	public double getY() {
		return _circle.getY();
	}

	@Override
	public double getCenterX() {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public double getCenterY() {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public void setLocation(double x, double y) {
		_bar.setFrame(x + _textWidth + _circleSize/2.0, y + (_circleSize - _barHeight)/2.0, _bar.getWidth(), _bar.getHeight());
		_circle.setFrame(x + _textWidth + _circleOff, y, _circle.getWidth(), _circle.getHeight());

	}

	@Override
	public double getWidth() {
		return (_bar.getWidth() + _textWidth + _circleSize);
	}

	@Override
	public double getHeight() {
		return (_circle.getHeight());
	}

	@Override
	public void setSize(double w, double h) {
		// TODO Auto-generated method stub

	}

}
